//
// Created by hjie on 23-9-20.
//

#include "nonce_data.h"
#include <cstdint>
#include <cstdlib>
#include <ctime>
#include <ios>
#include <mutex>

NonceDataManager::NonceDataManager()
{
    srand(time(nullptr));
}

void NonceDataManager::ProducerNonceData(bool save, std::string & content)
{
    uint8_t data[16] = {0};
    for (int i = 0; i < 16; i++)
    {
        data[i] = rand() % 256;
    }
    content = GetStringNonceData(data);
    NonceData nonce_data;
    memcpy(nonce_data.m_nonce_data, data, 16);
    nonce_data.m_update_time = time(nullptr);

    std::lock_guard<std::mutex> lk(m_nonce_mtx);
    m_nonce_map[content] = nonce_data;
}

std::string NonceDataManager::GetStringNonceData(uint8_t *nonce_data)
{
    char buff[128] = {0};
    int length = 0;
    for (int index = 0; index < 16; index++)
    {
        int i = snprintf(buff + length, sizeof(buff) - length, "%.2x", nonce_data[index]);
        length += i;
    }
    return buff;
}

void NonceDataManager::RefreshNonceData(const std::string &nonce_id)
{
    std::lock_guard<std::mutex> lk(m_nonce_mtx);
    auto iter = m_nonce_map.find(nonce_id);
    if (iter != m_nonce_map.end())
    {
        iter->second.m_update_time = time(nullptr);
    }
}

void NonceDataManager::NonceDataTimer()
{
    uint64_t now_time = time(nullptr);
    std::lock_guard<std::mutex> lk(m_nonce_mtx);
    for (auto iter = m_nonce_map.begin(); iter != m_nonce_map.end(); )
    {
        auto tmp = iter++;
        if ((now_time - tmp->second.m_update_time) >= 120)
        {
            m_nonce_map.erase(tmp);
        }
    }
}

bool NonceDataManager::CheckNonceData(const std::string & nonce_data)
{
    std::lock_guard<std::mutex> lk(m_nonce_mtx);

    bool result = m_nonce_map.find(nonce_data) != m_nonce_map.end();

    return result;
}

void NonceDataManager::UpdateNonceData(const std::string & data, int64_t now_time)
{
    int64_t update_time = 0;
    if (now_time > 0)
    {
        update_time = now_time;
    }
    else
    {
        update_time = time(nullptr);
    }
    std::lock_guard<std::mutex> lk(m_nonce_mtx);
    auto nonce_iter = m_nonce_map.find(data);
    if (nonce_iter != m_nonce_map.end())
    {
        nonce_iter->second.m_update_time = update_time;
    }
}
